﻿using System;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;

namespace WpfAdvControls.Component
{
    /// <summary>
    ///     Class SettingsBase<T> provides serialization/desirialization of T to Data catalog of a system.
    /// </summary>
    /// <typeparam name="T">Class with public properties that should be serialized</typeparam>
    public class SettingsBase<T> : ISettings<T>, IErrorInfo where T : new()
    {
        private readonly string settingId;

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="settingId">Identification of serialized class</param>
        public SettingsBase(string settingId)
        {
            this.settingId = settingId;
        }

        #region ISettings Members

        public T Settings { get; set; }

        public void LoadSettings()
        {
            try
            {
                var serializationFile = GetSerializationSettingFile();
                if (System.IO.File.Exists(serializationFile))
                {
                    try
                    {
                        var serializer = new XmlSerializer(typeof (T));
                        using (var fs = new FileStream(serializationFile, FileMode.OpenOrCreate))
                        {
                            Settings = (T) (serializer.Deserialize(fs));
                        }
                    }
                    catch (Exception ex)
                    {
                        IsError = true;
                        ErrorMessage = ex.ToString();
                        Settings = new T();
                    }
                }
                else
                {
                    Settings = new T();
                }
            }
            catch (Exception ex)
            {
                IsError = true;
                ErrorMessage = ex.ToString();
            }
        }

        public void SaveSettings()
        {
            try
            {
                var serializationFile = GetSerializationSettingFile();
                var serializer = new XmlSerializer(typeof (T));
                using (var fs = new FileStream(serializationFile, FileMode.Create))
                {
                    serializer.Serialize(fs, Settings);
                }
            }
            catch (Exception ex)
            {
                IsError = true;
                ErrorMessage = ex.ToString();
            }
        }

        private string settingSerializationFile;

        private string GetSerializationSettingFile()
        {
            if (settingSerializationFile == null)
            {
                var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

                settingSerializationFile = string.Format(@"{0}\{1}Settings.xml", appData, settingId);
            }
            return settingSerializationFile;
        }

        #endregion

        #region IErrorInfo Members

        private bool isError;

        public bool IsError
        {
            get { return isError; }
            set
            {
                isError = value;
                NotifyPropertyChanged("IsError");
            }
        }

        private string errorMessage;

        public string ErrorMessage
        {
            get { return errorMessage; }
            set
            {
                errorMessage = value;
                NotifyPropertyChanged("ErrorMessage");
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        #endregion
    }
}